/**
 * 
 */
package org.t2.game.server.foundation.player;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.gaming.ruler.lifecycle.Lifecycle;
import org.gaming.ruler.lifecycle.LifecycleInfo;
import org.gaming.ruler.lifecycle.Ordinal;
import org.gaming.ruler.lifecycle.Priority;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.ProtocolMessageEnum;

import pb.t2.protobuf.Wrapper.MessageWrapper;
import pb.t2.protobuf.player.Player.PbLogoutType;
import pb.t2.protobuf.player.Player.PlayerLogoutMessage;

/**
 * @author YY
 *
 */
@Service
public class PlayerContextManager implements Lifecycle {

	private static Logger logger = LoggerFactory.getLogger(PlayerContextManager.class);
	
	private ConcurrentMap<Long, PlayerContext> contexts = new ConcurrentHashMap<>();
	
	public PlayerContext getContext(long playerId) {
		return contexts.get(playerId);
	}
	
	/**
	 * 添加到在线集合
	 * @param playerContext
	 */
	public void addToOnline(PlayerContext playerContext) {
		contexts.put(playerContext.getId(), playerContext);
	}
	
	public void removeFromOnline(PlayerContext playerContext) {
		boolean removed = contexts.remove(playerContext.getId(), playerContext);
		logger.info("移除连接:" + playerContext.getId() + " " + removed);
	}
	
	/**
	 * 推送
	 * @param playerId
	 * @param proto
	 * @param msg
	 */
	public void push(long playerId, ProtocolMessageEnum proto, GeneratedMessageV3 msg) {
		PlayerContext playerContext = getContext(playerId);
		if(playerContext != null) {
			playerContext.write(proto, msg);
		}
	}
	
	public void pushAll(ProtocolMessageEnum proto, GeneratedMessageV3 msg) {
		MessageWrapper.Builder builder = MessageWrapper.newBuilder();
    	builder.setProtoId(proto.getNumber());
    	builder.setData(msg.toByteString());
    	byte[] data = builder.build().toByteArray();
    	for(PlayerContext playerContext : contexts.values()) {
    		playerContext.write(data);
    	}
	}
	
	public void pushSome(Collection<Long> playerIds, ProtocolMessageEnum proto, GeneratedMessageV3 msg) {
		MessageWrapper.Builder builder = MessageWrapper.newBuilder();
    	builder.setProtoId(proto.getNumber());
    	builder.setData(msg.toByteString());
    	byte[] data = builder.build().toByteArray();
    	for(Long playerId : playerIds) {
    		PlayerContext playerContext = getContext(playerId);
    		if(playerContext != null) {
    			playerContext.write(data);
    		}
    	}
	}
	
	public Collection<PlayerContext> onlines() {
		return contexts.values();
	}
	
	public boolean isOnline(long playerId) {
		return contexts.containsKey(playerId);
	}

	@Override
	public void stop() throws Exception {
		PlayerLogoutMessage.Builder message = PlayerLogoutMessage.newBuilder();
		message.setLogoutType(PbLogoutType.SERVER_MAINTAIN);
		this.pushAll(PlayerLogoutMessage.Proto.ID, message.build());
	}

	@Override
	public LifecycleInfo getInfo() {
		return LifecycleInfo.valueOf(this.getClass().getSimpleName(), Priority.LOW, Ordinal.MAX);
	}
}
